package com.zyj.reapiclientsdk.client;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import com.zyj.reapiclientsdk.utils.SignUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * API 调用
 * 通过该client转发请求到网关
 */
public class ReApiClient {

    private static String GATEWAY_HOST = "http://localhost:8090";

    /**
     * 访问密钥标识符
     */
    private String accessKey;

    /**
     * 访问密钥密钥
     */
    private String secretKey;

    public ReApiClient(String accessKey, String secretKey) {
        this.accessKey = accessKey;
        this.secretKey = secretKey;
    }

    public void setGatewayHost(String gatewayHost) {
        GATEWAY_HOST = gatewayHost;
    }

    public String invokeInterface(String params, String url, String path, String method){
        HttpResponse httpResponse = HttpRequest.post(GATEWAY_HOST + path)
                .header("Accept-Charset", CharsetUtil.UTF_8)
                .addHeaders(getHeaderMap(params, url, path, method))
                .body(params)
                .execute();
        return JSONUtil.formatJsonStr(httpResponse.body());
    }

    private Map<String, String> getHeaderMap(String params, String url, String path, String method) {
        HashMap<String, String> map = new HashMap<>();
        // accessKey：访问密钥
        map.put("accessKey", accessKey);
        // sign：客户端使用SignUtils生成签名作为入参，服务端通过相同的算法（body.ak）得到服务端sign，判断clientSign与serverSign是否相等
        map.put("sign", SignUtils.genSign(params, secretKey));
        // nonce：防重放
        map.put("nonce", RandomUtil.randomNumbers(10));
        // timestamp：防重放
        map.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
        String body = URLUtil.encode(params, CharsetUtil.CHARSET_UTF_8);
        map.put("body", body);
        // url & path & method：这三个参数主要用于判断调用接口是否存在，以及这个接口要转发到什么路径（具体的接口还是general）
        map.put("url", url);
        map.put("path", path);
        map.put("method", method);
        return map;
    }
}
